/*
 * CommonParameters.java
 *
 * Created on 7 de Julho de 2011, 17:29
 *
 */

package intopo.demonstrator;

import intopo.demonstrator.Event;
import util.math.Rational;
import java.util.Vector;
import java.util.TreeSet;

/**
 * Common parameters of the demonstrators stored in the sub packages of
 * {@code intopo.demonstrator}.  The common parameters control aspects of
 * the <i>partner selection</i> algorithm.  This algorithm uses a
 * probability vector.  Each slot represents the probability of selecting
 * an abstract set of partners.
 *
 * @author <a href="mailto:mariano.pedro@gmail.com">Pedro Mariano</a>
 *
 * @version 1.0 7 de Julho de 2011
 */
abstract public class CommonParameters
{
	/**
	 * Probability values in the probability vector are represented as
	 * integers.  This attribute holds the integer that represents the
	 * probability of a successful event.
	 * 
	 * In the Monte Carlo simulation we take into account the number of bits
	 * used to represent probability values.
	 */
	private int maxProbability;
	/**
	 * Size of the probability vector.
	 */
	private int poolSize;
	/**
	 * Numerator of the multiplication factor used when a probability is
	 * decreased because an unacceptable partner combination was chosen.
	 * This field represents parameter <i>&delta;</i> mentioned in the
	 * paper.
	 */
	private int deltaNumerator;
	/**
	 * Denominator of the multiplication factor used when a probability is
	 * decreased because an unacceptable partner combination was chosen.
	 * This field represents parameter <i>&delta;</i> mentioned in the
	 * paper.
	 */
	private int deltaDenominator;
	/**
	 * Creates a new instance of CommonParameters
	 */
	protected CommonParameters (int numberBitsProbability, int poolSize, Rational delta)
		throws IllegalArgumentException
	{
		this.setNumberBitsProbability (numberBitsProbability);
		this.setPoolSize (poolSize);
		this.setDelta (delta);
	}
	/**
	 * Copy constructor.
	 */
	protected CommonParameters (CommonParameters other)
	{
		this.maxProbability = other.maxProbability;
		this.poolSize = other.poolSize;
		this.deltaNumerator = other.deltaNumerator;
		this.deltaDenominator = other.deltaDenominator;
	}
	/**
	 * Return the number of bits used to encode probabilities in the
	 * probability vector.
	 */
	final public int getNumberBitsProbability ()
	{
		int result = 0;
		int b = this.maxProbability;
		while (b > 0) {
			result++;
			b = b >> 1;
		}
		return result;
	}
	/**
	 * Sets the number of bits used to encode probabilities in the
	 * probability vector.  We only store the maximum probability.  This
	 * method is equal to calling {@code
	 * setMaxProbability((1<<numberBitsProbability)-1)}.
	 *
	 * @param numberBitsProbability The new number of bits used to encode
	 * probabilities in the probability vector.
	 *
	 * @throws IllegalArgumentException If the parameter is less than one.
	 */
	final public void setNumberBitsProbability (int numberBitsProbability)
		throws IllegalArgumentException
	{
		if (numberBitsProbability < 1) {
			throw new IllegalArgumentException ("The number of bits used to encode probabilities in the probability vector must be strictly positive");
		}
		this.setMaxProbability ((1 << numberBitsProbability) - 1);
	}
	/**
	 * Sets the value that represents the probability of the event <i>select
	 * any combination in the probability vector</i>.
	 *
	 * <p> Probability values in the probability vector are represented as
	 * integers. In the Monte Carlo simulation we take into account the
	 * number of bits used to represent probability values in the
	 * probability vector.
	 *
	 * @throws IllegalArgumentException if the value is less than {@code 1}.
	 */
	final public void setMaxProbability (int maxProbability)
		throws IllegalArgumentException
	{
		if (maxProbability < 1) {
			throw new IllegalArgumentException ("The probability of a successfull event must be represented by a positive number");
		}
		this.maxProbability = maxProbability;
	}
	final public int getMaxProbability ()
	{
		return this.maxProbability;
	}
	/**
	 * Returns the value of the delta parameter.
	 * 
	 * <p> This method is used by the GUI components.  The user sees the
	 * delta as a rational number.  Internally the <i>delta</i> parameter is
	 * represented by two integers: the numerator and the denominator.
	 */
	final public Rational getDelta ()
	{
		return new Rational (deltaNumerator, deltaDenominator).simplify ();
	}
	/**
	 * Sets the value of the delta parameter.
	 * 
	 * <p> This method is used by the GUI components.  The user sees this
	 * parameter as a rational number.  Internally the <i>delta</i>
	 * parameter is represented by two integers: the numerator and the
	 * denominator.
	 */
	final public void setDelta (Rational delta)
		throws IllegalArgumentException
	{
		if (delta.compareTo (Rational.ZERO) <= 0 || delta.compareTo (Rational.ONE) > 0) {
			throw new IllegalArgumentException ("Delta must be strictly greater than 0 and less than or equal to 1");
		}
		deltaNumerator = delta.numerator ().intValue ();
		deltaDenominator = delta.denominator ().intValue ();
	}
	/**
	 * Return the numerator of the <i>delta</i> parameter.
	 *
	 * <p> Internally the <i>delta</i> parameter is represented by two
	 * integers: the numerator and the denominator.
	 */
	final public int getDeltaNumerator ()
	{
		return this.deltaNumerator;
	}
	/**
	 * Return the denominator of the <i>delta</i> parameter.
	 *
	 * <p> Internally the <i>delta</i> parameter is represented by two
	 * integers: the numerator and the denominator.
	 */
	final public int getDeltaDenominator ()
	{
		return this.deltaDenominator;
	}
	/**
	 * Get the size of the probability vector.
	 *
	 * @return the size of the probability vector.
	 */
	final public int getPoolSize ()
	{
		return this.poolSize;
	}
	/**
	 * Set the size of the probability vector.
	 *
	 * @param poolSize the new size of the probability vector.
	 *
	 * @throws IllegalArgumentException if the parameters is less than one.
	 */
	final public void setPoolSize (int poolSize)
		throws IllegalArgumentException
	{
		if (poolSize < 1) {
			throw new IllegalArgumentException ("Pool size must be strictly positive");
		}
		this.poolSize = poolSize;
	}
}

// Local Variables:
// mode: flyspell-prog
// mode: auto-complete
// ispell-local-dictionary: "british"
// End:
